package com.fruit.service.order.impl;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.fruit.constants.GoodsContant;
import com.fruit.constants.OrderConstant;
import com.fruit.constants.PayConstant;
import com.fruit.constants.SysMessageConstant;
import com.fruit.mapper.order.MailOrderMapper;
import com.fruit.mapper.order.OrderMapper;
import com.fruit.mapper.packageorder.OrderPackageMapper;
import com.fruit.mapper.packageorderdetail.OrderPackageDetailMapper;
import com.fruit.mapper.pay.PayMapper;
import com.fruit.mapper.sys.SysMapper;
import com.fruit.pojo.notice.NoticeMessage;
import com.fruit.pojo.order.DSHOrder;
import com.fruit.pojo.order.MailOrder;
import com.fruit.pojo.order.MyOrder;
import com.fruit.pojo.order.Order;
import com.fruit.pojo.order.OrderConfig;
import com.fruit.pojo.order.OrderGoods;
import com.fruit.pojo.orderpackage.OrderPackage;
import com.fruit.pojo.orderpackage.OrderPackageDetail;
import com.fruit.pojo.pay.TransactionFlow;
import com.fruit.pojo.promotion.ActivityGoods;
import com.fruit.pojo.queue.MultilParams;
import com.fruit.pojo.rights.UserGoodsRights;
import com.fruit.pojo.sys.SysConfig;
import com.fruit.pojo.user.sysmsg.SysMessage;
import com.fruit.sdk.account.commission.CommissionBackService;
import com.fruit.sdk.account.commission.RebateService;
import com.fruit.service.notice.NoticeMessageManager;
import com.fruit.service.order.DelayHandel;
import com.fruit.service.order.OrderManager;
import com.fruit.service.promotion.Promotion;
import com.fruit.service.queue.QueueBusHandel;
import com.fruit.service.redis.JedisUtil;
import com.fruit.service.rights.UserRightsManager;
import com.fruit.service.sysmsg.SysMessageService;
import com.fruit.util.CustomUtil;
import com.fruit.util.DataUtil;
import com.fruit.util.DateUtil;
import com.fruit.util.Exceptions;
import com.fruit.util.ResultInfo;
import com.fruit.util.ResultUtil;
import com.joe.utils.parse.json.JsonParser;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 订单业务逻辑类
 *
 * @author shibeilei
 * @version 2017.12.01 11:17
 *
 */
@Slf4j
@Service
public class OrderService implements OrderManager {

	@Autowired
	private OrderMapper orderMapper;

	@Autowired
	private MailOrderMapper mailOrderMapper;
	@Autowired
	private OrderPackageMapper orderPackageMapper;

	@Autowired
	private PayMapper payMapper;

	@Autowired
	private SysMapper sysMapper;

	@Value("${domain}")
	private String domain;

	@Autowired
	private JedisUtil jedisService;

	@Autowired
	private DelayHandel delayService;
	
	@Autowired
	private QueueBusHandel queueBusService;

	@Autowired
	private UserRightsManager userRightsService;

	@Autowired
	private CommissionBackService commissionBackService;

	@Autowired
	private RebateService rebateService;

	@Autowired
	private OrderLogService orderLogService;

	@Autowired
	private SysMessageService sysMessageService;

	@Autowired
	private NoticeMessageManager noticeMessageManager;

	@Autowired
	private OrderPackageDetailMapper orderPackageDetailMapper;

	@Autowired
	private Promotion promotionService;
	
	private static final JsonParser JSON = JsonParser.getInstance();

	@Override
	public Map<String, Object> updateOrderState(String tradeId, TransactionFlow tf) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		log.info("[{}]-【处理业务订单】-【开始】", tradeId);
		Order order = null;
		String serviceState = null;
		try {
			order = orderMapper.getOrderByTransactionId(tf.getId());
			if (order == null) {
				// 异常处理
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "order_null", "订单不存在!"));
				resMap.put("serviceState", OrderConstant.ServiceState.updateOrder.getValue());
				return resMap;
			}
			log.info("[{}]-【处理业务订单】-【订单号：{}】", tradeId, order.getCode());
			if (!OrderConstant.State.notpay.equals(order.getState())) {
				resMap.put("result",
						ResultUtil.initResult(ResultInfo.ERROR, "order_error", "订单状态更新失败!", null, ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.updateOrder.getValue());
				return resMap;
			}

			try {
				log.info("[{}]-【处理业务订单】-【从取消队列移除订单】", tradeId);
				// 从队列删除
				delayService.remove(order.getId());
				// 从redis删除
				jedisService.hdel(OrderConstant.ORDER_AUTO_CANCEL, order.getId() + "");
			} catch (Exception e) {
				e.printStackTrace();
				// 异常处理
				log.info("[{}]-【处理业务订单】-【从取消队列移除订单】-【异常】----{}", tradeId, getStackTraceAsString(e));
			}

			order.setState(OrderConstant.State.pay.getValue());
			order.setUpdateTime(DateUtil.getTime());
			log.info("[{}]-【处理业务订单】-【更新订单状态】", tradeId);
			int num = orderMapper.updateOrderStateById(order);
			if (num == 0) {
				// 异常处理
				log.error("[{}]-【处理业务订单】-【更新订单状态】-【失败】", tradeId);
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "order_update_fail", "订单状态更新失败!"));
				resMap.put("serviceState", OrderConstant.ServiceState.updateOrder.getValue());
				return resMap;
			}
			log.info("[{}]-【处理业务订单】-【更新订单状态】-【成功】", tradeId);

			if ("00".equals(order.getType())) {
				resMap = updateAdoptOrder(order, tf, tradeId);
			} else if ("01".equals(order.getType())) {
				resMap = saveMailOrder(order, tf, tradeId);
			} else {
				throw new Exception("订单状态错误");
			}
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				return resMap;
			}
			return resMap;
		} catch (Exception e) {
			e.printStackTrace();
			// 异常处理
			resMap.put("result",
					ResultUtil.initResult(ResultInfo.ERROR, "exception", "系统异常!", null, ResultInfo.ROLLBACK));
			resMap.put("serviceState", OrderConstant.ServiceState.updateOrder.getValue());
			return resMap;
		} finally {
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ROLLBACK.equals(ri.getIsRollBack())) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
			if (ResultInfo.ERROR.equals(ri.getState())) {
				log.error("[{}]-【处理业务订单】-【异常】-【{}：{}】", tradeId, ri.getCode(), ri.getMessage());
				if (order != null) {
					// 插入错误日志
					serviceState = (String) resMap.get("serviceState");
					orderLogService.newSaveExceptionOrder(tradeId, "OrderService", serviceState, order.getCode(),
							order.getUserId(), ri.getCode(), ri.getMessage());
				}
			} else {
				log.info("[{}]-【处理业务订单】-【成功】", tradeId);
			}
			log.info("[{}]-【处理业务订单】-【成功】", tradeId);
		}

	}

	/**
	 * 生成寄回订单
	 * 
	 * @param list
	 *            套餐订单详情
	 * @param record
	 *            套餐订单
	 * @param tradeId
	 *            流水号
	 * @return Map<String, Object>
	 */
	public Map<String, Object> saveMailOrder(Order order, TransactionFlow tf, String tradeId) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		log.info("【" + tradeId + "】---【生成寄回订单】---【开始】-----订单id:{}", order.getId());
		OrderPackage op = orderPackageMapper.selectById(order.getId()); // 获取套餐订单信息
		if (op == null) {
			log.error("[{}]-【获取套餐订单信息】--【失败】-订单id:{}", order.getId());
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "savemailorder_params", "寄回订单-获取主套餐订单异常", null,
					ResultInfo.ROLLBACK));
			resMap.put("serviceState", OrderConstant.ServiceState.updateOrder.getValue());
			return resMap;
		}
		log.info("【" + tradeId + "】---【获取套餐订单信息】-【成功】");
		// 修改套餐商品库存（真实售卖数量）
		Map<String, Object> saleParams = new HashMap<String, Object>();
		saleParams.put("id", op.getGoodsPackageId()); // 套餐id
		saleParams.put("num", op.getBuyNum()); // 购买数量
		log.info("【" + tradeId + "】---【更新套餐商品售卖数量】-【套餐商品ID：{}】-【购买数量：{}】", op.getGoodsPackageId(), op.getBuyNum());
		int saleNum = payMapper.updateAddPackageGoodsSaleNum(saleParams);
		if (saleNum == 0) {
			log.error("[{}]-【更新套餐商品售卖数量】--【失败】-【套餐商品ID：{}】-【购买数量：{}】", tradeId, op.getGoodsPackageId(), op.getBuyNum());
			// 异常处理
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "package_update_sale_num", "套餐商品更新已售数量失败",
					null, ResultInfo.ROLLBACK));
			resMap.put("serviceState", OrderConstant.ServiceState.updateFruit.getValue());
			return resMap;
		}
		log.info("【" + tradeId + "】---【更新套餐商品售卖数量】-【成功】");
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("orderId", order.getId());
		List<OrderPackageDetail> list = orderPackageDetailMapper.getRecordsByOrderId(params); // 获取套餐订单详情信息
		if (list.size() <= 0) {
			log.error("[{}]-【获取套餐订单详情信息】--【失败】-订单id:{}", order.getId());
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "savemailorder_params", "寄回订单-获取主套餐订单详情异常",
					null, ResultInfo.ROLLBACK));
			resMap.put("serviceState", OrderConstant.ServiceState.updateOrder.getValue());
			return resMap;
		}
		log.info("【" + tradeId + "】---【获取套餐订单详情信息】-【成功】");
		// 生成寄回订单
		for (OrderPackageDetail og : list) {
			MailOrder mailOrder = new MailOrder();
			mailOrder.setOrderId(og.getOrderId());
			mailOrder.setBaseId(og.getBaseId());
			mailOrder.setName(og.getGoodsName());
			mailOrder.setOrderGoodsId(og.getId());
			// 套餐id
			mailOrder.setOrderPackageId(op.getId());
			mailOrder.setUserId(og.getUserId());
			// 备注
			mailOrder.setRemark(op.getName() + "--" + og.getGoodsName());
			mailOrder.setNum(og.getBuyNum()); // 购买数量
			mailOrder.setUnit(og.getMeasureUnit());
			mailOrder.setExpectHarvest(og.getMeasureWeigh());
			mailOrder.setProvinceId(og.getReceiverProvinceId());
			mailOrder.setCityId(og.getReceiverCityId());
			mailOrder.setCountryId(og.getReceiverCountryId());
			mailOrder.setTownId(og.getReceiverTownId());
			mailOrder.setType("01"); // 套餐
			mailOrder.setReceiverName(og.getReceiverName());
			mailOrder.setReceiverPhone(og.getReceiverPhone());
			mailOrder.setReceiverAddress(og.getReceiverAddress());
			mailOrder.setDeliveryStartTime(og.getStartTime());
			mailOrder.setDeliveryEndTime(og.getEndTime());
			mailOrder.setCreateTime(DateUtil.getTime());
			mailOrder.setUpdateTime(DateUtil.getTime());
			mailOrderMapper.saveMailOrder(mailOrder); // 保存寄回订单
			mailOrder.setCode(CustomUtil.orderCode(3, mailOrder.getId(), mailOrder.getUserId()));
			int num = mailOrderMapper.updateMailOrderCode(mailOrder);
			if (num != 1) {
				log.error("【" + tradeId + "】---【生成寄回订单】---【失败】");
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "savemailorder_error", "生成寄回订单失败", null,
						ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.updateFruit.getValue());
				return resMap;
			}
		}
		resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "OK", "保存寄回订单成功!"));
		log.info("【" + tradeId + "】---【生成寄回订单】---【结束】-----");
		return resMap;
	}

	public Map<String, Object> updateAdoptOrder(Order order, TransactionFlow tf, String tradeId) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		int num = 0;
		log.info("[{}]-【处理业务订单】-【更新果树绑定状态】", tradeId);
		// 绑定果树
		List<OrderGoods> ogList = orderMapper.getOrderGoodsByOrderId(order.getId());
		Map<String, Object> params = new HashMap<String, Object>();
		StringBuffer sysMessage = new StringBuffer();
		for (OrderGoods og : ogList) {
			log.info("[{}]-【处理业务订单】-【更新库存】-【商品规格期次ID：{}】", tradeId, og.getGoodsSpecTimeId());
			num = payMapper.updateGoodsSpecTimeSaleNum(og);
			if (num == 0) {
				log.error("[{}]-【处理业务订单】-【更新库存】-【失败】", tradeId);
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "update_sale_num", "更新已售数量失败", null,
						ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.updateFruit.getValue());
				return resMap;
			}

			log.info("[{}]-【处理业务订单】-【更新库存】-【成功】", tradeId);

			String[] areaGoodsInfoIdsArray = StringUtils.split(og.getAreaGoodsInfoIds(), "|");
			if (areaGoodsInfoIdsArray == null || areaGoodsInfoIdsArray.length == 0) {
				// 异常处理
				resMap.put("result",
						ResultUtil.initResult(ResultInfo.ERROR, "binding_fail", "绑定失败", null, ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.updateFruit.getValue());
				return resMap;
			}
			for (String areaGoodsInfoIds : areaGoodsInfoIdsArray) {
				int idsNum = StringUtils.split(areaGoodsInfoIds, ",").length;
				params.clear();
				params.put("isBinding", GoodsContant.Binding.YES.getValue());
				params.put("areaGoodsInfoIds", areaGoodsInfoIds);
				params.put("userId", order.getUserId());
				params.put("endUseTime", og.getEndUseTime());
				num = payMapper.updateAreaGoodsNotUserBinding(params);
				if (idsNum != num) {
					// 异常处理
					resMap.put("result",
							ResultUtil.initResult(ResultInfo.ERROR, "binding_fail", "绑定失败", null, ResultInfo.ROLLBACK));
					resMap.put("serviceState", OrderConstant.ServiceState.updateFruit.getValue());
					return resMap;
				}
			}
			sysMessage.append(og.getNumber()).append(og.getUnitDesc()).append(og.getTitle()).append(",");
		}
		log.info("[{}]-【处理业务订单】-【更新果树绑定状态】-【成功】", tradeId);

		log.info("[{}]-【处理业务订单】-【生成寄回订单】-【开始】", tradeId);
		// 生成寄回订单
		for (OrderGoods og : ogList) {
			String[] harvests = StringUtils.split(og.getExpectHarvests(), ",");
			String[] harvestTimes = StringUtils.split(og.getHarvestTimes(), ",");
			String[] harvestIds = StringUtils.split(og.getHarvestIds(), ",");
			for (int i = 0; i < harvests.length; i++) {
				MailOrder mailOrder = new MailOrder();
				mailOrder.setOrderId(og.getOrderId());
				mailOrder.setBaseId(og.getBaseId());
				mailOrder.setName(og.getTitle());
				mailOrder.setOrderGoodsId(og.getId());
				mailOrder.setGoodsSpecTimeId(og.getGoodsSpecTimeId());
				mailOrder.setUserId(og.getUserId());
				mailOrder.setBatch(i + 1);
				mailOrder.setGoodsHarvestId(Integer.parseInt(harvestIds[i]));
				mailOrder.setNum(og.getNumber());
				mailOrder.setUnit(og.getHarvestUnit());
				mailOrder.setExpectHarvest(DataUtil.getBigDecimal(harvests[i]));
				mailOrder.setExpectHarvestTime(harvestTimes[i]);
				mailOrder.setProvinceId(og.getProvinceId());
				mailOrder.setCityId(og.getCityId());
				mailOrder.setCountryId(og.getCountryId());
				mailOrder.setTownId(og.getTownId());
				mailOrder.setType("00");
				mailOrder.setReceiverName(og.getReceiverName());
				mailOrder.setReceiverPhone(og.getReceiverPhone());
				mailOrder.setReceiverAddress(og.getReceiverAddress());
				mailOrder.setCreateTime(DateUtil.getTime());
				mailOrder.setUpdateTime(mailOrder.getCreateTime());
				num = mailOrderMapper.saveMailOrder(mailOrder);
				mailOrder.setCode(CustomUtil.orderCode(3, mailOrder.getId(), mailOrder.getUserId()));
				num = mailOrderMapper.updateMailOrderCode(mailOrder);
				if (num == 0) {
					log.error("[{}]-【处理业务订单】-【生成寄回订单】-【失败】", tradeId);
					resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "save_mail_order", "生成寄回订单失败", null,
							ResultInfo.ROLLBACK));
					resMap.put("serviceState", OrderConstant.ServiceState.updateFruit.getValue());
					return resMap;
				}
				// 生成通知消息
				insertNoticeMessage(tradeId, mailOrder, order.getCode(), og.getTitle());
			}
		}
		log.info("[{}]-【处理业务订单】-【生成寄回订单】-【结束】", tradeId);
		// 1、处理我的权益
		saveGoodsRight(tradeId, ogList, tf);
		// 2、发送站内信
		// insertSysMsg(sysMessage, tf.getUserId(), tradeId);
		// 3、落地处理数据
		((OrderService) AopContext.currentProxy()).newHandelActivity(ogList, tradeId, tf);

		resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "ok", "更新成功!"));

		return resMap;
	}

	/**
	 * 处理活动数据
	 * 
	 * @param ogList
	 * @param tradeId
	 */
	public void newHandelActivity(List<OrderGoods> ogList, String tradeId, TransactionFlow tf) {
		log.info("[{}]-【处理业务订单】-【处理活动数据】", tradeId);
		try {
			for (OrderGoods og : ogList) {
				log.info("[{}]-【处理业务订单】-【处理活动数据】-【参数{}:{}:{}】", tradeId, og.getOrderId(), og.getGoodsSpecTimeId(),
						og.getUserId());
				List<ActivityGoods> agList = promotionService.add(og.getOrderId(), og.getGoodsSpecTimeId(),
						og.getUserId());
				if (agList == null || agList.isEmpty()) {
					log.info("[{}]-【处理活动数据，商品ID：{}】-【没有参与的活动】", tradeId, og.getGoodsSpecTimeId());
					return;
				}
				for (ActivityGoods ag : agList) {
					if ("01".equals(ag.getType())) {
						log.info("[{}]-【处理活动数据】-【二级分润活动：活动ID：{}】", tradeId, ag.getActivityId());
						// 1、计算佣金
						insertCommBack(tradeId, tf);
					} else if ("02".equals(ag.getType())) {
						log.info("[{}]-【处理活动数据】-【多级分润活动：活动ID：{}】", tradeId, ag.getActivityId());
						//插入队列
						MultilParams multilParams = new MultilParams();
						multilParams.setTradeId(tradeId);
						multilParams.setType("multil_user");
						multilParams.setUserId(tf.getUserId());
						multilParams.setNum(og.getNumber());
						multilParams.setTransId(tf.getId());
						multilParams.setActivityId(ag.getActivityId());
						multilParams.setGoodsId(ag.getGoodsId());
						multilParams.setPrice(tf.getPayPrice());
						queueBusService.saveQueue(multilParams);
					} else {
						log.info("[{}]-【处理活动数据】-【没有对应活动处理：活动ID：{}】", tradeId, ag.getActivityId());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			// 异常处理
			log.error("[{}]-【处理业务订单】-【处理活动数据】-【异常】----{}", tradeId, getStackTraceAsString(e));
			orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
					OrderConstant.ServiceState.handelActivity.getValue(), tf.getCode(), tf.getUserId(),
					"handelNoticeException", "处理活动数据异常");
		}
	}

	/**
	 * 发送站内信
	 * 
	 * @param sysMessage
	 *            sysMessage
	 * @param userId
	 *            userId
	 * @param tradeId
	 *            tradeId
	 * @author shibeilei
	 * @version 2017.12.01 11:18
	 */
	public void insertSysMsg(StringBuffer sysMessage, int userId, String tradeId) {
		log.info("[{}]-【处理业务订单】-【发送站内信】", tradeId);
		try {
			SysMessage record = new SysMessage();
			record.setTitle("认养成功");
			record.setContent("恭喜您认养了" + sysMessage.substring(0, sysMessage.length() - 1));
			record.setUserId(userId);
			record.setType(SysMessageConstant.Type.buySuccess.getValue());
			record.setState(SysMessageConstant.State.no.getValue());
			record.setCreateTime(DateUtil.getTime());
			record.setUpdateTime(record.getCreateTime());
			record.setMsgType(SysMessageConstant.MsgType.notice.getValue());
			sysMessageService.insert(record);
		} catch (Exception e) {
			log.error("[{}]-【处理业务订单】-【发送站内信】-【异常】----{}", tradeId, getStackTraceAsString(e));
		}
		log.info("[{}]-【处理业务订单】-【发送站内信】-【结束】", tradeId);
	}

	/**
	 * 计算佣金
	 * 
	 * @param tradeId
	 *            tradeId
	 * @param tf
	 *            tf
	 * @author shibeilei
	 * @version 2017.12.01 11:25
	 */
	public void insertCommBack(String tradeId, TransactionFlow tf) {
		log.info("[{}]-【处理业务订单】-【处理佣金】", tradeId);
		try {
			Map<String, Object> resMap = new HashMap<>();
			SysConfig sc = sysMapper.getSysConfigList().get(0);
			if ("00".equals(sc.getRebateRoute())) {
				resMap = commissionBackService.insertCommBack(tradeId, tf.getUserId(), tf.getPayPrice(), tf.getId());
			} else {
				resMap = rebateService.insertRebate(tradeId, tf.getUserId(), tf.getPayPrice(), tf.getId());
			}
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				log.error("[{}]-【处理业务订单】-【处理佣金】-【异常】-【{}:{}】", tradeId, "handelCommBackError", "处理佣金失败");
				orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
						OrderConstant.ServiceState.handelCommission.getValue(), tf.getCode(), tf.getUserId(),
						"handelCommBackError", "处理佣金失败");

			} else {
				log.info("[{}]-【处理业务订单】-【处理佣金】-【成功】", tradeId);
			}
		} catch (Exception e) {
			log.error("[{}]-【处理业务订单】-【处理佣金】-【异常】----{}", tradeId, getStackTraceAsString(e));
			orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
					OrderConstant.ServiceState.handelCommission.getValue(), tf.getCode(), tf.getUserId(),
					"handelCommBackException", "处理佣金异常");
		}
		log.info("[{}]-【处理业务订单】-【处理佣金】-【结束】", tradeId);
	}

	/**
	 * 
	 * @param tradeId
	 * @param mo
	 * @param code
	 * @param title
	 */
	public void insertNoticeMessage(String tradeId, MailOrder mo, String code, String title) {
		log.info("[{}]-【处理业务订单】-【处理通知消息】", tradeId);
		try {
			NoticeMessage mn = new NoticeMessage();
			mn.setType("00");
			mn.setKeyword(title);
			mn.setCreateTime(DateUtil.getTime());
			mn.setObjId(mo.getGoodsHarvestId());
			mn.setUserId(mo.getUserId());
			Map<String, Object> resMap = noticeMessageManager.saveNoticeMessage(tradeId, mn);
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				log.error("[{}]-【处理业务订单】-【处理通知消息】-【异常】-【{}:{}】", tradeId, "handelRightError", "处理通知消息失败");
				orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
						OrderConstant.ServiceState.handelNotice.getValue(), code, mo.getUserId(), "handelNoticeError",
						"处理通知消息失败");

			} else {
				log.info("[{}]-【处理业务订单】-【处理通知消息】-【成功】", tradeId);
			}
		} catch (Exception e) {
			e.printStackTrace();
			// 异常处理
			log.error("[{}]-【处理业务订单】-【处理通知消息】-【异常】----{}", tradeId, getStackTraceAsString(e));
			orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
					OrderConstant.ServiceState.handelNotice.getValue(), code, mo.getUserId(), "handelNoticeException",
					"处理通知消息异常");
		}
	}

	/**
	 * 处理我的权益
	 * 
	 * @param tradeId
	 *            tradeId
	 * @param ogList
	 *            ogList
	 * @param tf
	 *            tf
	 * @author shibeilei
	 * @version 2017.12.01 11:25
	 */
	public void saveGoodsRight(String tradeId, List<OrderGoods> ogList, TransactionFlow tf) {
		log.info("[{}]-【处理业务订单】-【处理我的权益】", tradeId);
		try {
			// 插入我的权益
			String curTime = DateUtil.getTime();
			List<UserGoodsRights> ugrList = new ArrayList<UserGoodsRights>();
			log.info("[{}]-【处理业务订单】-【处理我的权益】-【封装权益参数】", tradeId);
			for (OrderGoods og : ogList) {
				UserGoodsRights ugr = new UserGoodsRights();
				ugr.setOrderGoodsId(og.getId());
				ugr.setBaseId(og.getBaseId());
				ugr.setBaseName(og.getBaseName());
				ugr.setClassId(og.getClassId());
				ugr.setGoodsSpecTimeId(og.getGoodsSpecTimeId());
				ugr.setGoodsName(og.getTitle());
				ugr.setThumb(og.getGoodsThumb());
				ugr.setThumbDay(og.getThumbDay());
				ugr.setThumbNight(og.getThumbNight());
				ugr.setUserId(og.getUserId());
				ugr.setTime(og.getTime());
				ugr.setExpectHarvests(og.getExpectHarvests());
				ugr.setExpectHarvestTimes(og.getHarvestTimes());
				ugr.setFruitPeriod(og.getFruitPeriod());
				ugr.setEquityCycle(og.getEquityCycle());
				ugr.setBirthday(og.getBirthday());
				ugr.setBuyTime(og.getBuyTime());
				ugr.setEndUseTime(og.getEndUseTime());
				ugr.setBuyTime(curTime);
				ugr.setNum(og.getNumber());
				ugr.setUnit(og.getUnit());
				ugr.setHarvestUnit(og.getHarvestUnit());
				ugr.setAreaGoodsInfoIds(og.getAreaGoodsInfoIds());
				ugr.setCreateTime(DateUtil.getTime());
				ugr.setUpdateTime(ugr.getCreateTime());
				ugrList.add(ugr);

			}
			Map<String, Object> resMap = userRightsService.insertGoodsRight(ugrList, tradeId);
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				log.error("[{}]-【处理业务订单】-【处理我的权益】-【异常】-【{}:{}】", tradeId, "handelRightError", "处理权益失败");
				orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
						OrderConstant.ServiceState.handelRights.getValue(), tf.getCode(), tf.getUserId(),
						"handelRightError", "处理权益失败");

			} else {
				log.info("[{}]-【处理业务订单】-【处理我的权益】-【成功】", tradeId);
			}

		} catch (Exception e) {
			e.printStackTrace();
			// 异常处理
			log.error("[{}]-【处理业务订单】-【处理我的权益】-【异常】----{}", tradeId, getStackTraceAsString(e));
			orderLogService.newSaveExceptionOrder(tradeId, "OrderService",
					OrderConstant.ServiceState.handelRights.getValue(), tf.getCode(), tf.getUserId(),
					"handelRightException", "处理权益异常");
		}
		log.info("[{}]-【处理业务订单】-【处理我的权益】-【结束】", tradeId);
	}

	/**
	 * 打印异常信息
	 * 
	 * @param ex
	 *            ex
	 * @return 返回异常信息
	 * @author shibeilei
	 * @version 2017.12.01 11:10
	 */
	public String getStackTraceAsString(Throwable ex) {
		StringWriter stringWriter = new StringWriter();
		ex.printStackTrace(new PrintWriter(stringWriter));
		return stringWriter.toString();
	}

	@Override
	public Map<String, Object> updateAutoCancelOrder(String tradeId, Order o, DSHOrder dshOrder) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		log.info("[{}]-【取消订单】-【业务处理】-【订单ID：{}】", tradeId, dshOrder.getOrderId());
		try {

			Order order = orderMapper.getOrderById(dshOrder.getOrderId());

			// 判断订单是否存在
			log.info("[{}]-【取消订单】-【判断订单是否存在】", tradeId);
			if (order == null) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "order_not_exists", "订单不存在!"));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
				return resMap;
			}
			o.setCode(order.getCode());
			o.setUserId(order.getUserId());
			// 判断订单支付类型
			log.info("[{}]-【取消订单】-【判断订单状态】", tradeId);
			if (!OrderConstant.State.notpay.equals(order.getState())) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "order_state_error", "订单状态不正确!"));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
				return resMap;
			}
			order.setState(OrderConstant.State.cancel.getValue());
			log.info("[{}]-【取消订单】-【更新订单状态】", tradeId);
			order.setUpdateTime(DateUtil.getTime());
			int num = orderMapper.updateOrderStateById(order);
			if (num == 0) {
				resMap.put("result",
						ResultUtil.initResult(ResultInfo.ERROR, "again_start", "订单状态取消失败!", null, ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
				return resMap;
			}

			// 更新账单状态
			log.info("[{}]-【取消订单】-【判断账单是否存在】", tradeId);
			TransactionFlow tf = payMapper.getTransactionFlowById(order.getTransactionId());
			if (tf == null) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "transaction_not_exists", "账单不存在!"));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
				return resMap;
			}
			log.info("[{}]-【取消订单】-【判断账单状态】", tradeId);
			if (!PayConstant.State.notpay.equals(tf.getState())) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "transaction_state_error", "账单状态不正确!"));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
				return resMap;
			}

			tf.setState(PayConstant.State.cancel.getValue());
			tf.setFinishTime(DateUtil.getTime());

			log.info("[{}]-【取消订单】-【更新账单状态】", tradeId);
			num = payMapper.updateTransactionFlowState(tf);
			if (num == 0) {
				resMap.put("result",
						ResultUtil.initResult(ResultInfo.ERROR, "again_start", "账单状态取消失败!", null, ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
				return resMap;
			}

			// 修改商品库存
			if ("00".equals(order.getType())) {
				resMap = updateGoodsTimeStock(tradeId, order);
				ResultInfo ri = (ResultInfo) resMap.get("result");
				if (ResultInfo.ERROR.equals(ri.getState())) {
					return resMap;
				}
			} else if ("01".equals(order.getType())) {
				resMap = updateAddStock(order, tradeId);
				ResultInfo re = (ResultInfo) resMap.get("result");
				if (ResultInfo.ERROR.equals(re.getState())) {
					return resMap;
				}
			}

			resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "ok", "取消成功!"));
			return resMap;
		} catch (Exception e) {
			log.error("[{}]-【取消订单】-【异常】-【{}：{}】----{}", tradeId, "cancelOrderException", "取消订单异常!",
					CustomUtil.getStackTraceAsString(e));
			resMap.put("result",
					ResultUtil.initResult(ResultInfo.ERROR, "exception", "系统异常!", null, ResultInfo.ROLLBACK));
			resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateOrder.getValue());
			return resMap;
		} finally {
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ROLLBACK.equals(ri.getIsRollBack())) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
	}

	public Map<String, Object> updateGoodsTimeStock(String tradeId, Order order) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		log.info("[{}]-【取消订单】-【更新商品库存】", tradeId);
		List<OrderGoods> ogList = orderMapper.getOrderGoodsByOrderId(order.getId());
		Map<String, Object> params = new HashMap<String, Object>();
		for (OrderGoods og : ogList) {
			log.info("[{}]-【取消订单】-【更新商品期次库存】-【商品期次ID：{}】", tradeId, og.getGoodsSpecTimeId());
			params.clear();
			params.put("id", og.getGoodsSpecTimeId());
			params.put("num", og.getNumber());
			int num = payMapper.updateAddGoodsSpecTimeStockNum(params);
			if (num == 0) {
				// 异常处理
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "again_start", "商品期次库存更新失败", null,
						ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateFruit.getValue());
				return resMap;
			}
			log.info("[{}]-【取消订单】-【更新商品区域库存】-【商品区域ID：{}】", tradeId, og.getAreaGoodsCountId());
			params.clear();
			params.put("id", og.getAreaGoodsCountId());
			params.put("takeNum", og.getNumber());
			params.put("takeState", "min");
			num = payMapper.updateAreaGoodsTakeNumByMap(params);
			if (num == 0) {
				// 异常处理
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "again_start", "商品区域库存更新失败", null,
						ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateFruit.getValue());
				return resMap;
			}
			String[] areaGoodsInfoIdsArray = StringUtils.split(og.getAreaGoodsInfoIds(), "|");
			if (areaGoodsInfoIdsArray == null || areaGoodsInfoIdsArray.length == 0) {
				// 异常处理
				resMap.put("result",
						ResultUtil.initResult(ResultInfo.ERROR, "again_start", "果树解绑失败", null, ResultInfo.ROLLBACK));
				resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateFruit.getValue());
				return resMap;
			}
			for (String areaGoodsInfoIds : areaGoodsInfoIdsArray) {
				int idsNum = StringUtils.split(areaGoodsInfoIds, ",").length;
				params.clear();
				params.put("isBinding", GoodsContant.Binding.NO.getValue());
				params.put("areaGoodsInfoIds", areaGoodsInfoIds);
				num = payMapper.updateAreaGoodsNotUserBinding(params);
				if (idsNum != num) {
					// 异常处理
					resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "again_start", "果树解绑失败", null,
							ResultInfo.ROLLBACK));
					resMap.put("serviceState", OrderConstant.ServiceState.cancelUpdateFruit.getValue());
					return resMap;
				}
			}

		}
		resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "ok", "认养解绑成功!"));
		return resMap;
	}

	/**
	 * 取消订单增加套餐产品库存
	 * 
	 * @param pi
	 *            提交订单参数
	 * @param tradeId
	 *            交易流水
	 * @return Map<String, Object>
	 */
	public Map<String, Object> updateAddStock(Order order, String tradeId) {
		Map<String, Object> result = new HashMap<String, Object>();
		log.info("【" + tradeId + "】---【更新套餐产品库存】---【开始】");
		try {
			Map<String, Object> params = new HashMap<String, Object>();
			OrderPackage op = orderPackageMapper.selectById(order.getId());
			log.info("【" + tradeId + "】---【更新套餐商品库存】-【套餐商品ID：{}】", op.getGoodsPackageId());
			params.put("id", op.getGoodsPackageId());
			params.put("num", op.getBuyNum());
			int num = payMapper.updateAddPackageGoodsStockNum(params);
			if (num == 0) {
				// 异常处理
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "again_start", "套餐商品库存更新失败", null,
						ResultInfo.ROLLBACK));
				result.put("serviceState", OrderConstant.ServiceState.cancelUpdateFruit.getValue());
				return result;
			}
			result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "ok", "套餐商品库存更新成功!"));
		} catch (Exception e) {
			log.error("【" + tradeId + "】---【更新套餐产品库存】---【异常！】-----" + Exceptions.getStackTraceAsString(e));
			result.put("result",
					ResultUtil.initResult(ResultInfo.ERROR, "again_start", "套餐商品库存更新异常！", null, ResultInfo.ROLLBACK));
		}
		log.info("【" + tradeId + "】---【更新套餐产品库存】---【结束】-----");
		return result;
	}

	@Override
	public void saveAutoCancelOrder(long orderId) {
		int timeOut = 900;
		List<OrderConfig> oc = orderMapper.getOrderConfig();
		if (oc != null && oc.size() == 1) {
			timeOut = oc.get(0).getAutoCancelTime();
		}

		DSHOrder order = new DSHOrder(orderId, timeOut);
		// 插入redis
		jedisService.hset(OrderConstant.ORDER_AUTO_CANCEL, orderId + "", order.getStartTime() + "");
		// 插入待取消队列
		delayService.add(order);

	}

	@Override
	public void newSaveAutoCancelOrder(long orderId) {
		try {
			int timeOut = 900;
			List<OrderConfig> oc = orderMapper.getOrderConfig();
			if (oc != null && oc.size() == 1) {
				timeOut = oc.get(0).getAutoCancelTime();
			}

			DSHOrder order = new DSHOrder(orderId, timeOut);
			// 插入redis
			jedisService.hset(OrderConstant.ORDER_AUTO_CANCEL, orderId + "", order.getStartTime() + "");
			// 插入待取消队列
			delayService.add(order);

			
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		}

	}

	/**
	 * 我的订单
	 * 
	 * @param params
	 *            用户ID 分页
	 * @return List<OrderGoods>
	 */
	@Override
	public List<MyOrder> getMyOrderByUserId(Map<String, Object> params) {
		// TODO Auto-generated method stub
		List<MyOrder> orderGoods = orderMapper.getMyOrderByUserId(params);
		if (orderGoods != null && orderGoods.size() > 0) {
			for (int i = 0; i < orderGoods.size(); i++) {
				MyOrder myOrder = orderGoods.get(i);
				if (StringUtils.isNotBlank(myOrder.getEndUseTime())) {
					if (DateUtil.compareDate2(DateUtil.getTime(), myOrder.getEndUseTime())) {
						myOrder.setState("00");// 如果当前时间 大于等于 截至使用时间 说明已经过期
					} else {
						myOrder.setState("01");// 否则没有过期
					}
				}
			}
		}
		return orderGoods;
	}

	@Override
	public List<NoticeMessage> getNotice() {
		Map<String, Object> resMap = new HashMap<String, Object>();
		log.info("【获取公告】---【开始】");
		List<MyOrder> getNot = orderMapper.getNotice();
		List<NoticeMessage> noticeList = new ArrayList<>();
		if (getNot.isEmpty()) {
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "transaction_not_exists", "没有公告 !"));
		} else {
			for (int i = 0; i < getNot.size(); i++) {
				NoticeMessage notice = new NoticeMessage();
				MyOrder getNOtOne = getNot.get(i);
				String phone = getNOtOne.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");// 处理后的电话号
				notice.setPhone(phone);
				notice.setTitle(getNOtOne.getTitle());
				noticeList.add(notice);
			}
		}
		log.info("【获取公告】---【结束】");
		return noticeList;
	}

}
